package io.github.wslxm.springbootplus2.starter.websocket.server;

import com.alibaba.fastjson.JSON;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import io.github.wslxm.springbootplus2.starter.websocket.model.entity.OnlineUser;
import io.github.wslxm.springbootplus2.starter.websocket.model.vo.SendMsgVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.buf.StringUtils;

import jakarta.websocket.Session;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * wensocket 提供的 api 方法
 *
 * @author wangsong
 * @date 2023/05/24
 */
@Slf4j
public class OpenWebSocketApi {

    /**
     * 消息发送（ 遍历用户Id , 在通过sendMsg方法发送消息）
     * <P>
     *     提供给外部或当前监听消息发送消息
     * </P>
     *
     * @param sendMsg：消息内容
     */
    public static void send(SendMsgVO sendMsg) {
        if (sendMsg == null
                || sendMsg.getTo() == null || "".equals(sendMsg.getTo())
                || sendMsg.getContent() == null || "".equals(sendMsg.getContent())
        ) {
            log.info("消息内容不完整或没有接收人: {}", sendMsg == null ? "" : JSON.toJSONString(sendMsg));
            return;
        }

        List<String> all = Arrays.asList("all", "ALL");
        if (all.contains(sendMsg.getTo())) {
            // 发送消息给所有人
            Set<String> userIds = WebsocketServer.getClients().keySet();
            for (String userId : userIds) {
                sendMsg(userId, sendMsg);
            }
        } else {
            // 发送消息给指定人
            String[] userIds = sendMsg.getTo().split(",");
            for (String userId : userIds) {
                sendMsg(userId, sendMsg);
            }
        }
    }


    /**
     * 消息发送(最后发送, 在send方法中循环用户Id 列表依次发送消息给指定人)
     * <p>
     * // 消息发送（同步:getBasicRemote 异步:getAsyncRemote）
     * </P>
     *
     * @param userId  消息接收人ID , onlineUsers 的 key
     * @param sendMsg 消息内容
     */
    private static boolean sendMsg(String userId, SendMsgVO sendMsg) {

        // 判断用户是否在线, 在线发送消息推送
        if (!WebsocketServer.getClients().containsKey(userId)) {
            // log.info("websocket用户ID:{} 不在线: 推送信息失败, 消息：{} ", userId, JSON.toJSONString(sendMsg));
            return false;
        }
        List<OnlineUser> onlineUsers = WebsocketServer.getClients().get(userId);
        for (OnlineUser onlineUser : onlineUsers) {
            Session session = onlineUser.getSession();
            if (session == null || !session.isOpen()) {
                continue;
            }
            try {
                // 此处存在同一个 session 可能被多个线程同时调用问题, 使用 synchronized 进行锁定排队执行
                synchronized (session) {
                    session.getBasicRemote().sendText(JSON.toJSONString(sendMsg));
                }
            } catch (IOException e) {
                log.error("发送消息失败: " + e.toString());
            }
        }
        return false;
    }


    public static void main(String[] args) {
        SendMsgVO sendMsgVO = new SendMsgVO();
        sendMsgVO.setFrom("1");
        sendMsgVO.setUsername("测试");
        sendMsgVO.setTo("2");
        sendMsgVO.setContent("测试信息");
        sendMsg("1", sendMsgVO);
    }
}
